import 'dart:ffi';
import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';

import '../../../dd_core/dd_http.dart';
import '../../../dd_core/dd_log_service.dart';
import '../../../dd_core/dd_other.dart';
import '../../../dd_core/dd_user_service.dart';
import '../../../dd_models/dd_oauth_model.dart';
import '../../../dd_models/dd_oos_model.dart';

class DDPersonalCenterController extends GetxController {
  final authModel = DDOauthModel().obs;
  final editNickName = "".obs;
  final editBirth = "".obs;
  final editCountry = "".obs;
  final availableCoins = Get.find<DDUserService>().availableCoins;

  RxnString editImageUrl = RxnString();

  final ImagePicker _picker = ImagePicker();

  TextEditingController control = TextEditingController();
  FocusNode focusNode = FocusNode();

  @override
  onInit() {
    super.onInit();
    authModel.value = Get.find<DDUserService>().authModel;
    authModel.refresh();
  }

  @override
  void onClose() {
    authModel.close();
    editNickName.close();
    editBirth.close();
    editCountry.close();
    editImageUrl.close();
    control.dispose();
    focusNode.dispose();
    super.onClose();
  }

  void copyUserId(BuildContext context) {
    _copyToClipboard(authModel.value.userinfo?.userId ?? '', context);
  }

  void _copyToClipboard(String text, BuildContext context) {
    Clipboard.setData(ClipboardData(text: text));
    _showSnackBar('Copy ID ${text} to the clipboard', context);
  }

  void _showSnackBar(String message, BuildContext context) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
      ),
    );
  }

  void requestPhotosPermission(BuildContext context) async {
    Permission permissionName;
    if (Platform.isIOS) {
      permissionName = Permission.photos;
    } else {
      final androidInfo = await DeviceInfoPlugin().androidInfo;
      final sdkInt = androidInfo.version.sdkInt;
      permissionName = sdkInt < 33 ? Permission.storage : Permission.photos;
    }
    PermissionStatus status = await permissionName.status;
    if (status.isDenied) {
      status = await permissionName.request();
      if (status.isPermanentlyDenied || status.isRestricted) {
        _showCustomPermissionDialog(context);
      } else if (status == PermissionStatus.granted) {
        _takeImageSource(_picker, ImageSource.gallery);
      }
    } else if (status.isPermanentlyDenied) {
      _showCustomPermissionDialog(context);
    } else {
      _takeImageSource(_picker, ImageSource.gallery);
    }
  }

  void requestCameraPermission(BuildContext context) async {
    Permission permission = Permission.camera;
    PermissionStatus status = await permission.status;
    if (status.isDenied) {
      status = await permission.request();
      if (status.isPermanentlyDenied || status.isRestricted) {
        _showCustomPermissionDialog(context);
      } else if (status == PermissionStatus.granted) {
        _takeImageSource(_picker, ImageSource.camera);
      }
    } else if (status.isPermanentlyDenied) {
      _showCustomPermissionDialog(context);
    } else {
      _takeImageSource(_picker, ImageSource.camera);
    }
  }

  _showCustomPermissionDialog(BuildContext context) {
    Get.dialog(
      DDPopAlert.title(
        description: 'You have not authorised this permission.',
        descriptionStyle: TextStyle(fontSize: 16, color: Color(0xFF222222)),
        contentInside: EdgeInsets.only(top: 30, bottom: 30),
        cancelTitle: "Cancel",
        okTitle: "OK",
        okBtnAction: () {
          openAppSettings();
        },
      ),
    );
  }

  void _takeImageSource(ImagePicker _picker, ImageSource source) async {
    try {
      final pickedFile = await _picker.pickImage(source: source);
      if (pickedFile?.path != null ) {
        DDLogService().ddGa(page: "editavatar");
        String imagePath = pickedFile!.path;
        String fileName = imagePath.split('/').last;
        final file = File(imagePath);
        final type_dir = await getTemporaryDirectory();
        final targetPath = '${type_dir.path}/$fileName';
        await FlutterImageCompress.compressAndGetFile(
          file.absolute.path,
          targetPath,
          quality: 30,
        );
        editImageUrl.value = targetPath;

      }
    } catch (e) {}
  }

  postProfile() {
    if (editImageUrl.value != authModel.value.userinfo?.avatarUrl) {
      updateAvatarFlow();
    } else {
      saveInfo(reload: false);
    }
  }

  Future<void> saveInfo({bool reload = true}) async {
    if (control.text != authModel.value.userinfo?.nickname ||
        editBirth.value != authModel.value.userinfo?.birthday ||
        editCountry.value != authModel.value.userinfo?.country) {
      if (!reload) {
        EasyLoading.show();
      }
      Map<String, dynamic>? result = await saveUserInfo(
          control.text, editBirth.value, editCountry.value);
      EasyLoading.dismiss();
      if (result != null && result['code'] == 0) {
        await Get.find<DDUserService>().reloadUserInfo();
        EasyLoading.showToast("success");
      } else {
        EasyLoading.showToast("save info failed");
      }
    } else {
      if (reload) {
        EasyLoading.dismiss();
        await Get.find<DDUserService>().reloadUserInfo();
        EasyLoading.showToast("success");
      }
    }
  }

  Future<void> updateAvatarFlow() async {
    try {
      EasyLoading.show();
      final result = await ossPolicy();
      if (!isValidResult(result)) throw Exception('Avatar upload failed');

      final model = DDOssModel.fromJson(result!['data']);
      final uploadResult = await uploadImageOss(model, editImageUrl.value!);
      if (!isValidResult(uploadResult) ||
          uploadResult!["data"]["filename"] == null) {
        throw Exception('Avatar upload failed');
      }

      final filePath = uploadResult["data"]["filename"];
      final updateAvatarResult = await updateAvatar(filePath);
      if (!isValidResult(updateAvatarResult))
        throw Exception('Avatar upload failed');
      saveInfo();
    } catch (e) {
      EasyLoading.dismiss();
      EasyLoading.showToast(e.toString());
    }
  }

  bool isValidResult(Map<String, dynamic>? result) {
    return result != null && result['code'] == 0;
  }
}
